#!/bin/bash
# Desc: 院长多功能防火墙管理脚本（支持firewalld/iptables）
# Author: 院长
# Web: https://deanit.cn
# Date: 2025-03-12
# 初始化变量
FIREWALL_TYPE=""
CONFIG_BACKUP_DIR="/var/firewall_backup"
IPTABLES_RULES_FILE="$CONFIG_BACKUP_DIR/iptables.rules"
FIREWALLD_ZONE_FILE="$CONFIG_BACKUP_DIR/firewalld_zones.xml"
# 检测root权限
check_root() {
    if [ "$EUID" -ne 0 ]; then
        echo "错误：必须使用root权限运行此脚本"
        exit 1
    fi
}
# 检测防火墙类型
detect_firewall() {
    if systemctl is-active --quiet firewalld; then
        FIREWALL_TYPE="firewalld"
    elif systemctl is-active --quiet iptables; then
        FIREWALL_TYPE="iptables"
    else
        echo "警告：未找到活动的防火墙服务，将尝试安装..."
        install_firewall
    fi
}
# 安装防火墙服务
install_firewall() {
    read -p "请选择要安装的防火墙类型 (1. firewalld 2. iptables): " choice
    case $choice in
        1)
            yum install -y firewalld
            systemctl enable --now firewalld
            FIREWALL_TYPE="firewalld"
            ;;
        2)
            yum install -y iptables-services
            systemctl enable --now iptables
            FIREWALL_TYPE="iptables"
            ;;
        *)
            echo "无效选择，退出..."
            exit 1
            ;;
    esac
}
# 防火墙状态管理
manage_service() {
    case $FIREWALL_TYPE in
        firewalld)
            systemctl $1 firewalld
            ;;
        iptables)
            systemctl $1 iptables
            ;;
    esac
}
# 通用端口操作
port_operation() {
    read -p "请输入端口号: " port
    read -p "请输入协议类型 (tcp/udp): " protocol
    case $1 in
        add)
            case $FIREWALL_TYPE in
                firewalld)
                    firewall-cmd --permanent --add-port=$port/$protocol
                    firewall-cmd --reload
                    ;;
                iptables)
                    iptables -A INPUT -p $protocol --dport $port -j ACCEPT
                    service iptables save
                    ;;
            esac
            ;;
        remove)
            case $FIREWALL_TYPE in
                firewalld)
                    firewall-cmd --permanent --remove-port=$port/$protocol
                    firewall-cmd --reload
                    ;;
                iptables)
                    iptables -D INPUT -p $protocol --dport $port -j ACCEPT
                    service iptables save
                    ;;
            esac
            ;;
    esac
}
# IP地址管理
ip_management() {
    read -p "请输入IP地址: " ip
    read -p "请输入操作类型 (allow/block): " action
    case $FIREWALL_TYPE in
        firewalld)
            if [ "$action" = "allow" ]; then
                firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='$ip' accept"
            else
                firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='$ip' reject"
            fi
            firewall-cmd --reload
            ;;
        iptables)
            if [ "$action" = "allow" ]; then
                iptables -A INPUT -s $ip -j ACCEPT
            else
                iptables -A INPUT -s $ip -j DROP
            fi
            service iptables save
            ;;
    esac
}
# NAT配置管理
nat_management() {
    case $1 in
        add)
            read -p "请输入内网接口: " internal_if
            read -p "请输入外网接口: " external_if
            iptables -t nat -A POSTROUTING -o $external_if -j MASQUERADE
            iptables -A FORWARD -i $external_if -o $internal_if -m state --state RELATED,ESTABLISHED -j ACCEPT
            iptables -A FORWARD -i $internal_if -o $external_if -j ACCEPT
            echo 1 > /proc/sys/net/ipv4/ip_forward
            service iptables save
            ;;
        remove)
            iptables -t nat -F POSTROUTING
            iptables -F FORWARD
            service iptables save
            ;;
    esac
}
# 端口转发
port_forward() {
    read -p "请输入源端口: " src_port
    read -p "请输入目标IP: " dest_ip
    read -p "请输入目标端口: " dest_port
    read -p "请输入协议类型 (tcp/udp): " protocol
    case $FIREWALL_TYPE in
        firewalld)
            firewall-cmd --permanent --add-forward-port=port=$src_port:proto=$protocol:toport=$dest_port:toaddr=$dest_ip
            firewall-cmd --reload
            ;;
        iptables)
            iptables -t nat -A PREROUTING -p $protocol --dport $src_port -j DNAT --to $dest_ip:$dest_port
            service iptables save
            ;;
    esac
}
# 配置备份
backup_config() {
    mkdir -p $CONFIG_BACKUP_DIR
    case $FIREWALL_TYPE in
        firewalld)
            firewall-cmd --runtime-to-permanent
            cp /etc/firewalld/zones/*.xml $CONFIG_BACKUP_DIR
            ;;
        iptables)
            iptables-save > $IPTABLES_RULES_FILE
            ;;
    esac
    echo "配置已备份至 $CONFIG_BACKUP_DIR"
}
# 配置恢复
restore_config() {
    case $FIREWALL_TYPE in
        firewalld)
            cp $CONFIG_BACKUP_DIR/*.xml /etc/firewalld/zones/
            firewall-cmd --reload
            ;;
        iptables)
            iptables-restore < $IPTABLES_RULES_FILE
            service iptables save
            ;;
    esac
    echo "配置已从备份恢复"
}
# 实时日志监控
monitor_logs() {
    echo "选择日志类型："
    echo "1. 实时防火墙日志"
    echo "2. 最近20条拒绝记录"
    read -p "请输入选择: " log_choice
    case $log_choice in
        1)
            tail -f /var/log/messages | grep -E 'iptables|firewalld'
            ;;
        2)
            journalctl -u $FIREWALL_TYPE | grep -i 'denied' | tail -n 20
            ;;
        *)
            echo "无效选择"
            ;;
    esac
}
# 显示菜单
show_menu() {
    clear
    echo "========================================"
    echo "  院长多功能防火墙管理脚本 ($FIREWALL_TYPE)"
    echo "========================================"
    echo "1. 启动防火墙服务"
    echo "2. 停止防火墙服务"
    echo "3. 重启防火墙服务"
    echo "4. 添加端口"
    echo "5. 删除端口"
    echo "6. IP白名单/黑名单管理"
    echo "7. NAT配置管理"
    echo "8. 端口转发配置"
    echo "9. 备份当前配置"
    echo "10. 恢复备份配置"
    echo "11. 查看防火墙状态"
    echo "12. 实时日志监控"
    echo "13. 切换防火墙类型"
    echo "0. 退出"
    echo "========================================"
}
# 主程序
main() {
    check_root
    detect_firewall
    while true; do
        show_menu
        read -p "请输入选项: " choice
        case $choice in
            1) manage_service start ;;
            2) manage_service stop ;;
            3) manage_service restart ;;
            4) port_operation add ;;
            5) port_operation remove ;;
            6) ip_management ;;
            7) 
                echo "1. 添加NAT规则"
                echo "2. 删除NAT规则"
                read -p "请选择: " nat_choice
                [ "$nat_choice" = "1" ] && nat_management add
                [ "$nat_choice" = "2" ] && nat_management remove
                ;;
            8) port_forward ;;
            9) backup_config ;;
            10) restore_config ;;
            11) 
                case $FIREWALL_TYPE in
                    firewalld) firewall-cmd --list-all ;;
                    iptables) iptables -L -n -v ;;
                esac
                ;;
            12) monitor_logs ;;
            13) install_firewall ;;
            0) exit 0 ;;
            *) echo "无效选项，请重新输入" ;;
        esac
        read -p "按回车键继续..."
    done
}
# 执行主程序
main